package com.android.publicModule.tools;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.UUID;

/**
 * 
 * 版权所有：版权所有(C) 2012，掌众传媒
 * 文件编号: 文件名称:
 * 系统编号： 系统名称：
 * 组件编号：
 * 组件名称：
 * 设计作者：zhujiehua
 * 完成日期：2013-7-16 
 * 设计文档：
 * 设计模型:
 * 内容摘要：获取唯一标示id
 */
public class DeviceIDFactory {
	private static final String ZZ_ERROR_TAG = "mid";
	protected static final String PREFS_FILE = "yy_id.xml";
	protected static final String PREFS_DEVICE_ID = "yy_id_key2";
	private final String MID_PATH_TF_SYS = "/sys";
	private final String MID_PATH_TF_ZZ = "/zzWare";
	private final String YYMID_NAME = "MID.bin";// TF卡中存储的ID
	private final String strIdName = "_$$YY_UUID$$__";
	private final String YYID_TAG = "yyid";
	protected static UUID uuid;
	private String mid ="";
	
	public static boolean checkMID(Context context) 
	{
		boolean fRet = false;
		String strMid = new DeviceIDFactory(context).getMID();
		if ( null != strMid && strMid.length() > 0 )
			fRet = true;
		return fRet;
	}
	private String generateUUID(Context context) throws UnsupportedEncodingException
	{
		String strRet = YYID_TAG;
		String strId;
		final String androidId = Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);
		//处理可能出现出厂时生成的androidID相同的情况
		if (!"9774d56d682e549c".equals(androidId)) {
			uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
		} else {
			final String deviceId = ((TelephonyManager) context
					.getSystemService(Context.TELEPHONY_SERVICE))
					.getDeviceId();
			uuid = deviceId != null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
		}
		strId = dealUUID(uuid.toString());
		if( null == strId || strId.equals("") )
		{
			// 用自己的方法生成这个id
		}
		return strRet + strId;
	}
	private void SaveUUID(Context context,String strId)
	{
		//存储UUID到三个位置(系统设置、软件内部、TF(sys、zzWare))
		if( null != strId && !strId.equals("") )
		{
			final SharedPreferences prefs = context.getSharedPreferences(PREFS_FILE, 0);
			//保存到系统
			saveUUID(context, strId);
			//保存到软件
			saveUUID(prefs, strId);
			/**
			 * 保存到TF卡
			 */
			//位置： /sys
			saveUUID(this.MID_PATH_TF_SYS, mid, this.YYMID_NAME);
		
			//位置： /zzWare
			saveUUID(this.MID_PATH_TF_ZZ, mid, this.YYMID_NAME);
		}
		
	}
	public DeviceIDFactory(Context context) {
			synchronized (DeviceIDFactory.class) {
					// 获取UUID
					mid = getDeviceID(context);
					//if ( null == mid || mid.equals(""))
					if ( !isValidDeviceID(mid) )
					{
						try 
						{
							mid = generateUUID(context);
						} catch (UnsupportedEncodingException e) {
							throw new RuntimeException(e);
						}
					}
					SaveUUID(context, mid);
			}
	}
	
	/**
	 * 处理UUID 截取后16位数据
	 * @param ids
	 * @return
	 */
	private String dealUUID(String ids) {
		try {
			String strPadding = "0123456789abcdef";
			String[] strs = ids.split("-");
			String strId = "";
			for ( String Id : strs )
				strId += Id;
			if ( strId.length() < 16 )
				strId = strPadding + strId; 
			ids = strId.substring(strId.length() - 16);
			//ids = strs[3] + strs[4];
		} catch (Exception e) {
			ids = "";
		}
		return ids;
	}

	/**
	 * 获取标识ID
	 * @param context
	 * @return
	 */
	private String getDeviceID(Context context) {
		// 读取系统数据库UUID
		String strRet = "";
		String str = Settings.System.getString(context.getContentResolver(),this.strIdName);
		if (str == null) 
		{
			// 读取软件类别UUDI
			SharedPreferences prefs = context.getSharedPreferences(PREFS_FILE,0);
			str = prefs.getString(PREFS_DEVICE_ID, null);
			if (str == null || str.equals("")) 
			{
				// 读取TF卡UUID
				//获取sd卡目录： /sys/yyMID.bin  文件ID信息
				String sdsysID = getUUIDFrom_TF_File(this.MID_PATH_TF_SYS + "/"+ this.YYMID_NAME);
				str = sdsysID;
				if(null == sdsysID || sdsysID.equals(""))
				{
					//获取sd卡目录： /zzWare/yyMID.bin  文件ID信息
					String sdzzID = getUUIDFrom_TF_File(this.MID_PATH_TF_ZZ + "/"+ this.YYMID_NAME);
					str = sdzzID;
				}
			}
		}
		if ( null != str )
			strRet = str;
		else
		{
		}
		return strRet;
	}
	private boolean isAlpha(char ch)
	{
		boolean fRet = false;
		if ( (ch >= '0' && ch <= '9') || 
			 (ch >= 'a' && ch <= 'z') ||
			 (ch >= 'A' && ch <= 'Z'))
		{
			fRet = true;
		}
		return fRet;
	}
	private boolean isValidDeviceID(String strId) 
	{		
		// mid的长度为20位，是以yyid开头，后面16位的字符为0-9和a-z
		boolean fValid = false;
		if ( null != strId && strId.length() == 20 )
		{
			int i;
			char ch;
			if ( strId.startsWith(YYID_TAG) )
			{
				for ( i = YYID_TAG.length() ; i < strId.length() ; i++ )
				{
					ch = strId.charAt(i);
					if ( !isAlpha(ch) )
					{
						break;
					}
				}
				if ( i >= strId.length() )
					fValid = true;
			}
		}
		return fValid;
	}
	
	/**
	 * 系统保存UUID
	 * @param context
	 * @param ID
	 */
	private void saveUUID(Context context, String ID) {
		try {
			
			Settings.System.putString(context.getContentResolver(),strIdName, ID);
		} catch (Exception e) {
			Tools.showLog(ZZ_ERROR_TAG, this.getClass().getName()+":"+e.getMessage());
		}
	}

	/**
	 * 应用中保存UUID
	 * @param pre
	 * @param ID
	 */
	private void saveUUID(SharedPreferences pre, String ID) {
		pre.edit().putString(PREFS_DEVICE_ID, ID).commit();
	}

	/**
	 * TF中保存UUID
	 * @param path
	 * @param ID
	 * @param fileName
	 */
	private void saveUUID(String path, String ID,String fileName) {
		String sdcarPaht = Environment.getExternalStorageDirectory().getAbsolutePath();
		File file = new File(sdcarPaht+"/"+path);
		//不存在此文件则创建
		if(!file.exists()){
			file.mkdirs();
		}
		
		//将ID写入文件
		try {
			file = new File(sdcarPaht+"/"+path+"/"+fileName);
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(ID.getBytes());
			fos.flush();
			fos.close();
		} catch (FileNotFoundException e) {
			Tools.showLog(ZZ_ERROR_TAG, "UUID error:"+e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			Tools.showLog(ZZ_ERROR_TAG, "UUID error:"+e.getMessage());
			e.printStackTrace();
		}
	}
	
	/**
	 * 从TF卡中获取UUID
	 * @param fileName
	 * @return
	 */
	private String getUUIDFrom_TF_File(String fileName){
		
		String sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
		File f = new File(sdCardPath + fileName);
		if(false ==f.exists()){
			return "";
		}
		try {
			FileReader fr = new FileReader(f);
			BufferedReader br = new BufferedReader(fr);
			String strTem = "";
			StringBuffer sb = new StringBuffer();
			while ((strTem = br.readLine())!=null) {
				sb.append(strTem);
			}
			fr.close();
			br.close();
			return sb.toString();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return "";
		} catch (IOException e) {
			e.printStackTrace();
			return "";
		}
	}
	
	public String getMID(){
		Tools.showLog(ZZ_ERROR_TAG,"mid:"+mid);
		return mid;
	}
}